'''
遍历联合路由密码，获得解密路径

矩阵为5行*4列
'''

import sys

ciphertext =  '''16 12 8 4 0 1 5 9 13 17 18 14 10 6 2 3 7 11 15 19''' #带解密字符串

COLS = 4 #矩阵列数
ROWS = 5 #矩阵行数

key = '''-1 2 -3 4''' #解密路径

'''
检查用户输入的内容是否有效(判断矩阵行/列是否合法)
    创建一个列表储存密合法的行/列数目
    获取密文列表长度
    遍历循环判断用户输入是否合法
        如果合法添加进密文列表
    如果不合法输出错误提示
'''
def validate_col_row(cipherlist):
    factor = []
    len_cipher = len(cipherlist)
    for i in range(2,len_cipher): #密文矩阵最少需要两列所以从第二列开始循环
        if len_cipher % i == 0:
            factor.append(i)
    print('\n矩阵共有:{}个元素'.format(len_cipher))
    print('\n可接受的列/行值包括:{}'.format(factor))
    print()
    if COLS * ROWS != len_cipher:
        print('输入的行列不满足密文矩阵要求',file=sys.stderr)
    sys.exit(1)

'''
将秘钥从字符串转换成整数列表
    将秘钥列表推导成整数
    曲秘钥最大值和最小值
    判断秘钥是否合法
        不合法输出错误提示
        合法返回秘钥列表
'''
def key_to_init(key):
    key_init = [int(i) for i in key.split()]
    key_init_lo = min(key_init)
    key_init_max = max(key_init)
    if len(key_init) != COLS or key_init_lo<-COLS or key_init_max>COLS or 0 in key_init: #因为秘钥的长度决定矩阵行数
        print('秘钥存在错误',file=sys.stderr)
        sys.exit(1)
    else:
        return key_init

'''
构建换位矩阵
    使用占位符创建矩阵列表
    设定起始位和结束位
    判断秘钥路径
    设置每一列矩阵阅读路径
    返回矩阵列表
'''
def build_matrix(key_init, cipherlist):
    translation_matrix = [None] * COLS
    start = 0
    stop = ROWS
    for k in key_init:
        if k < 0:
            col_items = ciphertext[start:stop]
        elif k >0:
            col_items = list(reversed(ciphertext[start:stop]))
        translation_matrix[abs(k)-1] = col_items
        start += ROWS
        stop += ROWS
    return translation_matrix

'''
解密矩阵列表获取明文
    储存文明的字符串
    遍历矩阵列表每列取出每列最后一个元素就是明文
'''
def decrypt(translation_matrix):
    plaintext = ''
    for i in range(ROWS):
        for matrix_col in translation_matrix:
            word = str(matrix_col.pop())
            plaintext += word+''
    return plaintext


def main():
    print('\n密文:{}'.format(ciphertext))
    print('\n矩阵行数:{}'.format(COLS))
    print('\n矩阵列数:{}'.format(ROWS))

    cipherlist = list(ciphertext.split()) #将密文拆分成单词，而非字母放入列表中
    validate_col_row(cipherlist) #检查用户输入的内容是否有效
    key_init = key_to_init(key) #将秘钥从字符串转换成整数列表
    translation_matrix = build_matrix(key_init,cipherlist) #构建和解密换位矩阵
    plaintext = decrypt(translation_matrix) #获得明文消息
    print('\n解密:{}'.format(plaintext))

if __name__ == '__main__':
    main()